package collections

import (
	"sync"
)

// 队列 ---- 链表实现,类似于LinkedBlockingQueue
// 每个节点的结构体
type node struct {
	value interface{}
	pre   *node
	next  *node
}

// 链表结构体
type LinkedQueue struct {
	lock sync.Mutex
	head *node // 定义头尾指针
	tail *node
	size int
}

func (q *LinkedQueue) Size() int {
	return q.size
}

func (q *LinkedQueue) Push(data interface{}) {
	q.lock.Lock()
	defer q.lock.Unlock()

	newNode := &node{
		value: data,
		pre:   q.tail,
		next:  nil,
	}
	// 初始化
	if q.tail == nil {
		q.head = newNode
		q.tail = newNode
	} else {
		q.tail.next = newNode
		q.tail = newNode
	}

	q.size++
}

func (q *LinkedQueue) Pull() node {
	q.lock.Lock()
	defer q.lock.Unlock()
	if q.head == nil {
		panic("empty queue")
	}

	head := q.head
	q.head = head.next // 指针后移
	q.size--
	return *head
}

// 基于切片实现，类似于ArrBlockingQueue
type Queue struct {
	data []interface{}
	// 锁
	lock sync.Mutex
}

func (q *Queue) Push(data interface{}) {
	q.lock.Lock()
	defer q.lock.Unlock()

	q.data = append(q.data, data)
}

func (q *Queue) Pull() interface{} {
	q.lock.Lock()
	defer q.lock.Unlock()

	if len(q.data) > 0 {
		v := q.data[0]
		q.data = q.data[1:]
		return v
	}
	return nil
}
